﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

using DNA;
using TJADRICD.CollaborativeDesignPlugin.Form;
using TJADRICD.CollaborativeDesignPlugin.Function;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using DBTransMan = Autodesk.AutoCAD.DatabaseServices.TransactionManager;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.PlottingServices;


namespace TJADRICD.CollaborativeDesignPlugin
{
    class CommandSign
    {
        public static string path = "";
        public static ObjectId GetLastObjectId(Database db)
        {
            List<Entity> list = new List<Entity>();
            Editor ed = Tools.Editor;
            PromptSelectionResult result = ed.SelectAll();
            ObjectIdCollection col = new ObjectIdCollection(result.Value.GetObjectIds());
            if (col.Count > 0)
            {
                return col[0];
            }
            else
                throw new System.Exception("当前空间没有对象");
        }
 
        static public string makeSubProDir(string prono, string subprono, string major)
        {
            string fatherPath = "";
            string majorAnother = "";
            foreach (string webPath_t in Config.ProjectPath)
            {
                String webPath = webPath_t;
                if(webPath.EndsWith(@"\\"))
                {
                    webPath = webPath.Substring(0, webPath.Length - 1);
                }
                DirectoryInfo Dir_Web = new DirectoryInfo(webPath);
                DirectoryInfo[] Dir_Pros = Dir_Web.GetDirectories();
                foreach (DirectoryInfo Dir_Pro in Dir_Pros)
                {
                    if (Dir_Pro.Name == prono)
                    {
                        fatherPath = webPath;
                    }
                }
            }
            switch (major)
            {
                case "建筑":
                    majorAnother = "JZ";
                    break;
                case "结构":
                    majorAnother = "JG";
                    break;
                case "给排水":
                    majorAnother = "GPS";
                    break;
                case "电力":
                    majorAnother = "DL";
                    break;
                case "暖通":
                    majorAnother = "NT";
                    break;
                case "强电":
                    majorAnother = "QD";
                    break;
                case "弱电":
                    majorAnother = "RD";
                    break;
                default:
                    return "";
            }   
            return fatherPath + prono + "\\" + subprono + "\\Common\\TZ\\" + majorAnother + "\\";
        }

        public static ObjectId ImportFileAsBlock(Database destDb, string sourceFileName, string blockName)
        {
            Database db = new Database(false, true);
            db.ReadDwgFile(sourceFileName, FileShare.Read, true, "");
            ObjectId idNewBTR = destDb.Insert(blockName, db, false);
            return idNewBTR;
        }
        //从某文件引入所有块定义到某db，返回插入的块定义ids
        public static void ImportBlocks(Database destDb, string sourceFileName)
        {
            Database sourceDb = new Database(false, true);
            try
            {
                // Read the DWG into a side database
                sourceDb.ReadDwgFile(sourceFileName,
                                    System.IO.FileShare.Read,
                                    true,
                                    "");
                // Create a variable to store the list of block identifiers
                ObjectIdCollection blockIds = new ObjectIdCollection();
                Autodesk.AutoCAD.DatabaseServices.TransactionManager tm =
                  sourceDb.TransactionManager;
                using (Transaction myT = tm.StartTransaction())
                {
                    // Open the block table
                    BlockTable bt =
                        (BlockTable)tm.GetObject(sourceDb.BlockTableId,
                                                OpenMode.ForRead,
                                                false);
                    // Check each block in the block table
                    foreach (ObjectId btrId in bt)
                    {
                        BlockTableRecord btr =
                          (BlockTableRecord)tm.GetObject(btrId,
                                                        OpenMode.ForRead,
                                                        false);
                        // Only add named & non-layout blocks to the copy list
                        if (!btr.IsAnonymous && !btr.IsLayout)
                            blockIds.Add(btrId);

                        btr.Dispose();
                    }
                }
                // Copy blocks from source to destination database
                IdMapping mapping = new IdMapping();
                sourceDb.WblockCloneObjects(blockIds,
                                            destDb.BlockTableId,
                                            mapping,
                                            DuplicateRecordCloning.Replace,
                                            false);
                //                 Tools.WriteMessageWithReturn("\nCopied "
                //                                 + blockIds.Count.ToString()
                //                                 + " block definitions from "
                //                                 + sourceFileName
                //                                 + " to the current drawing.");
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Tools.WriteMessageWithReturn("\nError during copy: " + ex.Message);
            }
            sourceDb.Dispose();
        }

        public static void SignDB(Database db, string signerName, List<string> signItems, bool hand)
        {
            try
            {
                ;
                string strHashCode = Function_Hash.GetDwgHash(db);
/*                List<ObjectId> list_id = new List<ObjectId>();*/
                Tools.WriteMessageWithReturn("开始处理" + db.Filename);
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    //先检查有没有图框
//                     List<Point3d> poss = new List<Point3d>();   //存放插入签名的位置
//                     List<double> rotations = new List<double>();    //每个签名的旋转角度
                    BlockTable table = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
/*                    BlockTableRecord signRecord = null;*/
                    BlockReference frameRef = null;
                    foreach (ObjectId blockId in table)
                    {
                        BlockTableRecord record = (BlockTableRecord)trans.GetObject(blockId, OpenMode.ForRead);
                        //Tools.WriteMessageWithReturn(record.Name);
                        if (CommandFrame.IsVersionType(record.Name))  //如果此块定义名符合图框块名
                        {
                            ObjectIdCollection blockRefIds = record.GetBlockReferenceIds(true, true);  //取得此块定义所关联的所有块参照Id
                            foreach (ObjectId blockRefId in blockRefIds)
                            {
                                BlockReference blockRef = (BlockReference)trans.GetObject(blockRefId, OpenMode.ForWrite);
                                frameRef = blockRef;
                                AttributeCollection blockRefAttrs = blockRef.AttributeCollection;
                                foreach (ObjectId attrRefId in blockRefAttrs)
                                {
                                    AttributeReference attrRef = (AttributeReference)trans.GetObject(attrRefId, OpenMode.ForWrite);
                                    foreach (string signItem in signItems)
                                    {
                                      

                                        if ((attrRef.Tag == signItem + "SignPos") && (attrRef.TextString == ""))
                                        {
                                            Xrecord xrec = new Xrecord();
                                            xrec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, strHashCode), new TypedValue((int)DxfCode.Text, Function_Hash.GetSingleMD5String(frameRef)));

                                            if (frameRef.ExtensionDictionary == ObjectId.Null)
                                            {
                                                frameRef.CreateExtensionDictionary();
                                            }


                                            ObjectId entDictID = frameRef.ExtensionDictionary;

                                            DBDictionary entXrecord = trans.GetObject(entDictID, OpenMode.ForWrite) as DBDictionary;

                                            if (entXrecord.Contains(signItem))
                                            {
                                                entXrecord.Remove(signItem);
                                            }
                                            entXrecord.SetAt(signItem, xrec);
                                            trans.AddNewlyCreatedDBObject(xrec, true);
                                            foreach (ObjectId attrRefId2 in blockRefAttrs)
                                            {
                                                AttributeReference attrRef2 = (AttributeReference)trans.GetObject(attrRefId2, OpenMode.ForWrite);
                                                if (attrRef2.Tag == signItem)
                                                {
//                                                     poss.Add(attrRef2.Position);
                                                    //                                                     rotations.Add(attrRef2.Rotation);

                                                    attrRef2.TextString = signerName;
                                                }
                                                else if ((attrRef2.Tag == signItem + "Date")/* && (attrRef.TextString == "00.00.00")*/)
                                                {
                                                    attrRef2.TextString = DateTime.Now.ToString("yy.MM.dd");
                                                }
                                            }
                                            if (hand)
                                            {
                                                attrRef.TextString = "hand";
                                            }
                                            else
                                            {
                                                attrRef.TextString = signerName;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
#region 
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//                     if (poss.Count > 0)
//                     {
//                         //Tools.WriteMessageWithReturn("找到图框");
//                         //引入签名块定义
//                         //ImportFileAsBlock(db, Convention.HandwritingDirectory + signerName + ".dwg", "sign_"+signerName);
//                         string fileName = signerName;
//                         if (hand == true)
//                         {
//                             fileName = "hand";
//                         }
//                         Tools.WriteMessageWithReturn(Convention.HandwritingDirectory + fileName + ".dwg");
//                         try
//                         {
// //                            MessageBox.Show(Convention.HandwritingDirectory + fileName + ".dwg");
//                             ImportBlocks(db, Convention.HandwritingDirectory + fileName + ".dwg");
//                         }
//                         catch(System.Exception e)
//                         {
//                             MessageBox.Show(e.ToString() + "\nFile not found: " + Convention.HandwritingDirectory + fileName + ".dwg");
//                         }
//                         //得到刚才插入的图框块定义
//                         foreach (ObjectId btrId in table)
//                         {
//                             BlockTableRecord btr =
//                               (BlockTableRecord)trans.GetObject(btrId,
//                                                             OpenMode.ForWrite,
//                                                             false);
//                             if (!btr.IsAnonymous && btr.Name == "sign_" + fileName)
//                             {
//                                 signRecord = btr;
//                                 if (fileName == "hand")
//                                 {
//                                     try
//                                     {
//                                         btr.Name = "sign_hand_" + signerName;
//                                     }
//                                     catch (System.Exception ex)
//                                     {
//                                     	foreach (ObjectId id in table)
//                                         {
//                                             BlockTableRecord btr2 = trans.GetObject(id, OpenMode.ForRead) as BlockTableRecord;
//                                             if (!btr2.IsAnonymous && btr2.Name == "sign_hand_" + signerName)
//                                             {
//                                                 signRecord = btr2;
//                                             }
//                                         }
//                                     }
//                                 }
//                                 //Tools.WriteMessageWithReturn("找到签名块定义" + btr.Name);
//                                 break;
//                             }
//                         }
//                         //对每一个签名位置进行插入
//                         BlockTableRecord modelSpace = (BlockTableRecord)trans.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// 
//                         Tools.WriteMessageWithReturn("共计" + poss.Count.ToString() + "个签名");
//                         //Tools.WriteMessageWithReturn("全局Hash值:" + strHashCode);
//                         for (int i = 0; i < poss.Count; i++)
//                         {
//                             Point3d pos = poss[i];
//                             //Tools.WriteMessageWithReturn(signRecord.ObjectId.ToString());
// //                            MessageBox.Show(signRecord.ObjectId.ToString());
//                             BlockReference blockRef = new BlockReference(pos, signRecord.ObjectId);
//                             Scale3d scale = new Scale3d(50);
//                             blockRef.ScaleFactors = frameRef.ScaleFactors;
//                             blockRef.Rotation = rotations[i];
//                             modelSpace.AppendEntity(blockRef);
//                             trans.AddNewlyCreatedDBObject(blockRef, true);
// 
//                             Entity ent = trans.GetObject(blockRef.ObjectId, OpenMode.ForWrite) as Entity;
// 
//                             Xrecord xrec = new Xrecord();
//                             xrec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, strHashCode), new TypedValue((int)DxfCode.Text, DwgHash.GetSingleMD5String(ent)));
// 
//                             //Tools.WriteMessageWithReturn(i.ToString()+".签名Hash值:"+DwgHash.GetSingleMD5String(ent));
// 
//                             ent.CreateExtensionDictionary();
// 
//                             ObjectId entDictID = ent.ExtensionDictionary;
// 
//                             DBDictionary entXrecord = trans.GetObject(entDictID, OpenMode.ForWrite) as DBDictionary;
// 
//                             entXrecord.SetAt("MyXrecord", xrec);
//                             trans.AddNewlyCreatedDBObject(xrec, true);
//                             //Tools.WriteMessageWithReturn("Success");
//                         }
//                     }
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                    trans.Commit();
                }
//                 Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(db.Filename, false);
//                 Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
//                 doc.LockDocument();
//                 Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0);
//                 Database db2 = doc.Database;
//                 
//                 using (Transaction tr = db2.TransactionManager.StartTransaction())
//                 {
//                     String MachineName = "DWG To PDF.pc3";
// 
//                     BlockTable bt = tr.GetObject(db2.BlockTableId, OpenMode.ForRead) as BlockTable;
//                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
//                     Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);
// 
//                     PlotInfo pi = new PlotInfo();
//                     pi.Layout = btr.LayoutId;
//                     PlotSettings ps = new PlotSettings(lo.ModelType);
// 
//                     ps.CopyFrom(lo);
//                     PlotSettingsValidator psv = PlotSettingsValidator.Current;
// 
//                     psv.SetUseStandardScale(ps, true);
//                     psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
//                     psv.SetPlotCentered(ps, true);
// 
//                     System.Collections.Specialized.StringCollection clo2 = psv.GetPlotDeviceList();
//                     foreach (String MN in clo2)
//                     {
//                         Tools.WriteMessageWithReturn(MN);
//                     }
// 
//                     System.Collections.Specialized.StringCollection clo3 = psv.GetCanonicalMediaNameList(ps);
// 
//                     foreach (String PN in clo3)
//                     {
//                         Tools.WriteMessageWithReturn(PN);
// 
//                         String mediana = psv.GetLocaleMediaName(ps, PN);
//                         Tools.WriteMessageWithReturn(mediana);
// 
//                     }
//                     System.Collections.Specialized.StringCollection sl = psv.GetPlotStyleSheetList();
// 
//                     Tools.WriteMessageWithReturn(MachineName);
//                     psv.SetPlotConfigurationName(ps, MachineName, "ISO_A0_(841.00_x_1189.00_MM)");
// 
//                     psv.GetPlotStyleSheetList();
// 
//                     Double minX = 0;
//                     Double minY = 0;
//                     Double maxX = 0;
//                     Double maxY = 0;
// 
//                     foreach (ObjectId blockId in bt)
//                     {
//                         BlockTableRecord record = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
//                         if (record.Name.StartsWith("TJAD_TK_A") || record.Name.StartsWith("TJAD_TK_N"))
//                         {
//                             // Tools.WriteMessageWithReturn(record.Name);
//                             ObjectIdCollection blockRefIds = record.GetBlockReferenceIds(true, true);
//                             Tools.WriteMessageWithReturn(record.Name);
//                             Tools.WriteMessageWithReturn(blockRefIds.Count.ToString());
//                             foreach (ObjectId blockRefId in blockRefIds)
//                             {
//                                 BlockReference blockRef = (BlockReference)tr.GetObject(blockRefId, OpenMode.ForRead);
// 
//                                 Entity ent = tr.GetObject(blockRefId, OpenMode.ForWrite) as Entity;
//                                 if (ent.ExtensionDictionary == ObjectId.Null)
//                                 {
//                                     Tools.WriteMessageWithReturn("null");
//                                     return;
//                                 }
//                                 DBDictionary entXrecord = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
//                                 ObjectId xrecordId = entXrecord.GetAt("MyXrecord");
//                                 Xrecord xrecord = tr.GetObject(xrecordId, OpenMode.ForRead) as Xrecord;
//                                 ResultBuffer rb = xrecord.Data;
//                                 string ctbName = null;
//                                 foreach (TypedValue value in rb)
//                                 {
//                                     ctbName = value.Value.ToString();
//                                 }
//                                 Tools.WriteMessageWithReturn(ctbName);
//                                 psv.SetCurrentStyleSheet(ps, ctbName);
// 
//                                 Extents3d ext = blockRef.GeometricExtents;
//                                 Point3d PT1 = ext.MaxPoint;
//                                 Point3d PT2 = ext.MinPoint;
//                                 minX = System.Math.Min(PT1.X, PT2.X);
//                                 minY = System.Math.Min(PT1.Y, PT2.Y);
//                                 maxX = System.Math.Max(PT1.X, PT2.X);
//                                 maxY = System.Math.Max(PT1.Y, PT2.Y);
//                             }
//                         }
//                     }
// 
//                     Extents2d e2d = new Extents2d(minX, minY, maxX, maxY);
//                     psv.SetPlotWindowArea(ps, e2d);
//                     psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.View);
// 
//                     psv.SetPlotRotation(ps, PlotRotation.Degrees090);
// 
//                     pi.OverrideSettings = ps;
// 
//                     PlotInfoValidator piv = new PlotInfoValidator();
//                     piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
//                     piv.Validate(pi);
// 
//                     PlotEngine pe = PlotFactory.CreatePublishEngine();
//                     using (pe)
//                     {
//                         PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
//                         using (ppd)
//                         {
//                             ppd.set_PlotMsgString(
//                               PlotMessageIndex.DialogTitle,
//                               "正在打印"//"Custom Plot Progress"
//                             );
//                             ppd.set_PlotMsgString(
//                               PlotMessageIndex.CancelJobButtonMessage,
//                               "取消当前打印"//"Cancel Job"
//                             );
//                             ppd.set_PlotMsgString(
//                               PlotMessageIndex.CancelSheetButtonMessage,
//                               "取消本页打印"//"Cancel Sheet"
//                             );
//                             ppd.set_PlotMsgString(
//                               PlotMessageIndex.SheetSetProgressCaption,
//                               "打印集合进度"//"Sheet Set Progress"
//                             );
//                             ppd.set_PlotMsgString(
//                               PlotMessageIndex.SheetProgressCaption,
//                               "打印页进度"//"Sheet Progress"
//                             );
//                             ppd.LowerPlotProgressRange = 0;
//                             ppd.UpperPlotProgressRange = 100;
//                             ppd.PlotProgressPos = 0;
// 
//                             ppd.OnBeginPlot();
//                             ppd.IsVisible = true;
//                             pe.BeginPlot(ppd, null);
// 
//                             FileInfo fi = new FileInfo(db2.Filename);
//                             DirectoryInfo di = fi.Directory;
//                             pe.BeginDocument(pi, doc.Name, null, 1, true, di.Parent.FullName + @"\PB\" + fi.Name.Substring(0, (fi.Name.Length - 4)));
// 
//                             // Which contains a single sheet
// 
//                             ppd.OnBeginSheet();
// 
//                             ppd.LowerSheetProgressRange = 0;
//                             ppd.UpperSheetProgressRange = 100;
//                             ppd.SheetProgressPos = 0;
// 
//                             PlotPageInfo ppi = new PlotPageInfo();
//                             pe.BeginPage(ppi, pi, true, null);
//                             pe.BeginGenerateGraphics(null);
//                             pe.EndGenerateGraphics(null);
// 
//                             // Finish the sheet
//                             pe.EndPage(null);
//                             ppd.SheetProgressPos = 100;
//                             ppd.OnEndSheet();
// 
//                             // Finish the document
// 
//                             pe.EndDocument(null);
// 
//                             // And finish the plot
// 
//                             ppd.PlotProgressPos = 100;
//                             ppd.OnEndPlot();
//                             pe.EndPlot(null);
// 
//                         }
//                     }
//                 }
//                 
//                 Document c = Application.DocumentManager.MdiActiveDocument;
//                 c.CloseAndDiscard();
#endregion
            }
            catch (System.Exception ex)
            {
                Tools.WriteMessageWithReturn(ex.Message + ex.StackTrace);
            }

        }
        //对于一个Database进行签名，针对signItems所包含的位置进行签名
        public static void SignDB(Database db, string signerName, List<string> signItems)
        {
            if (signerName == "")
            {
                return;
            }
            SignDB(db, signerName, signItems,false);
        }

        public static void SignDB(Database db, Dictionary<string, string> signItems, DateTime signDate, bool hand)
        {
            string hashCode = Function_Hash.GetDwgHash(db);
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable table = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
                BlockReference frame = null;
                BlockTableRecord frameRec = null;
                foreach (ObjectId recordId in table)
                {
                    BlockTableRecord frameRecord = trans.GetObject(recordId, OpenMode.ForWrite) as BlockTableRecord;
                    if (CommandFrame.IsVersionType(frameRecord.Name))
                    {
                        ObjectIdCollection ids = frameRecord.GetBlockReferenceIds(true, true);
                        frameRec = frameRecord;
                        if (ids.Count == 0)
                        {
                            continue;
                        }
                        foreach (ObjectId referenceId in ids)
                        {
                            frame = trans.GetObject(referenceId, OpenMode.ForWrite) as BlockReference;
                            break;
                        }
                    }
                }
                if (frame == null)
                {
                    return;
                }
                foreach (KeyValuePair<string, string> signItem in signItems)
                {
                    SignSingle(db, trans, frameRec, frame, signItem, signDate, hand, frame.ScaleFactors);
                }
            }
        }

        public static void SignSingle(Database db, Transaction trans, BlockTableRecord frameRecord, BlockReference frame, KeyValuePair<string, string> signItem, DateTime signDate, bool hand, Scale3d scale)
        {
            string hashCode = Function_Hash.GetDwgHash(db);
            BlockTable table = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
            BlockTableRecord modelSpace = trans.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
            string fileName;
            AttributeCollection ac = frame.AttributeCollection;
            BlockTableRecord signRecord = null;
            if (hand)
            {
                fileName = "hand";
            }
            else
            {
                fileName = signItem.Value;
            }
            foreach (ObjectId AttrRefId in ac)
            {
                AttributeReference AttrRef = trans.GetObject(AttrRefId, OpenMode.ForWrite) as AttributeReference;
                if ((AttrRef.Tag == signItem.Key) && (AttrRef.TextString == ""))
                {
                    foreach (ObjectId attrRefId2 in ac)
                    {
                        AttributeReference attrRef2 = (AttributeReference)trans.GetObject(attrRefId2, OpenMode.ForWrite);
                        if (attrRef2.Tag == signItem + "SignPos")
                        {
                            ImportBlocks(db, Config.HandwritingPath + fileName + ".dwg");
                            foreach (ObjectId btrId in table)
                            {
                                BlockTableRecord btr =
                                  (BlockTableRecord)trans.GetObject(btrId,
                                                                OpenMode.ForWrite,
                                                                false);
                                if (!btr.IsAnonymous && btr.Name == "sign_" + fileName)
                                {
                                    signRecord = btr;
                                    if (fileName == "hand")
                                    {
                                        try
                                        {
                                            btr.Name = "sign_hand_" + signItem.Value;
                                        }
                                        catch
                                        {
                                            foreach (ObjectId id in table)
                                            {
                                                BlockTableRecord btr2 = trans.GetObject(id, OpenMode.ForRead) as BlockTableRecord;
                                                if (!btr2.IsAnonymous && btr2.Name == "sign_hand_" + signItem.Value)
                                                {
                                                    signRecord = btr2;
                                                }
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                            BlockReference blockRef = new BlockReference(attrRef2.Position, signRecord.ObjectId);
                            blockRef.ScaleFactors = scale;
                            blockRef.Rotation = attrRef2.Rotation;
                            modelSpace.AppendEntity(blockRef);
                            trans.AddNewlyCreatedDBObject(blockRef, true);

                            Entity ent = trans.GetObject(blockRef.ObjectId, OpenMode.ForWrite) as Entity;

                            Xrecord xrec = new Xrecord();
                            xrec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, hashCode), new TypedValue((int)DxfCode.Text, Function_Hash.GetSingleMD5String(ent)));

                            //Tools.WriteMessageWithReturn(i.ToString()+".签名Hash值:"+DwgHash.GetSingleMD5String(ent));

                            ent.CreateExtensionDictionary();

                            ObjectId entDictID = ent.ExtensionDictionary;

                            DBDictionary entXrecord = trans.GetObject(entDictID, OpenMode.ForWrite) as DBDictionary;

                            entXrecord.SetAt("MyXrecord", xrec);
                            trans.AddNewlyCreatedDBObject(xrec, true);
                        }
                    }
                    AttrRef.TextString = signItem.Value;
                }
                if ((AttrRef.Tag == signItem + "Date") && (AttrRef.TextString == "00.00.00"))
                {
                    AttrRef.TextString = signDate.ToString("yy.MM.dd");
                }
            }
        }

        //对于一个Database删除签名，针对unsignItems所包含的位置删除签名
        public static void UnsignDB(Database db, List<string> unsignItems)
        {
            try
            {
                Tools.WriteMessageWithReturn("开始处理" + db.Filename);
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    //先检查有没有图框
                    List<Point3d> poss = new List<Point3d>();   //存放插入签名的位置
                    BlockTable table = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
//                    List<BlockReference> signBlockRefs = new List<BlockReference>();
                    foreach (ObjectId blockId in table)
                    {
                        BlockTableRecord record = (BlockTableRecord)trans.GetObject(blockId, OpenMode.ForRead);
                        if (CommandFrame.IsVersionType(record.Name))  //如果此块定义名符合图框块名
                        {
                            ObjectIdCollection blockRefIds = record.GetBlockReferenceIds(true, true);  //取得此块定义所关联的所有块参照Id
                            foreach (ObjectId blockRefId in blockRefIds)
                            {
                                BlockReference blockRef = (BlockReference)trans.GetObject(blockRefId, OpenMode.ForRead);
                                AttributeCollection blockRefAttrs = blockRef.AttributeCollection;
                                ObjectId dicID = blockRef.ExtensionDictionary;
                                DBDictionary dictionary = null;
                                if (dicID != ObjectId.Null)
                                {
                                    dictionary = trans.GetObject(dicID, OpenMode.ForWrite) as DBDictionary;
                                }
                                foreach (string signItem in unsignItems)
                                {
                                    if (dicID != ObjectId.Null)
                                    {
                                        dictionary.Remove(signItem);
                                    }
                                    foreach (ObjectId attrRefId in blockRefAttrs)
                                    {
                                        AttributeReference attrRef = (AttributeReference)trans.GetObject(attrRefId, OpenMode.ForWrite);
                                        if (attrRef.Tag == signItem + "SignPos")
                                        {
                                            attrRef.TextString = "";
                                        }
                                        if (attrRef.Tag == signItem)
                                        {
                                            attrRef.TextString = "";
                                        }
                                        if (attrRef.Tag == signItem + "Date")
                                        {
                                            attrRef.TextString = "00.00.00";
                                        }
                                    }
                                }
                            }
                        }
                     }
                    trans.Commit();
                }
            }
            catch (System.Exception ex)
            {
                Tools.WriteMessageWithReturn(ex.Message + ex.StackTrace);
            }

        }
        [CommandMethod("SignThisFile")]
        public static void SignThisFile()
        {
            Database db = Tools.Database;
            Editor ed = Tools.Editor;
            //PromptOpenFileOptions opts = new PromptOpenFileOptions("选择签名文件");
            //opts.Filter = "Dwawing(*.dwg)|*.dwg";
            //PromptFileNameResult                                                                                                                                                                                                                                                                    pr = ed.GetFileNameForOpen(opts);
            SignDB(db, "李刚", new List<string>(new string[] { "ApprovedBy" }));

        }

        public static void GoThroughDirectory(string dir, ref List<string> files)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(dir);
            FileInfo[] fileInfos = dirInfo.GetFiles();
            foreach (FileInfo fileInfo in fileInfos)
            {
                if (Path.GetExtension(fileInfo.Name) == ".dwg")
                    files.Add(fileInfo.FullName);
            }
            DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
            foreach (DirectoryInfo subDirInfo in dirInfos)
            {
                GoThroughDirectory(subDirInfo.FullName, ref files);
            }
        }
        [CommandMethod("SignFiles")]
        public void SignFiles()
        {
            SignControl formSignControl = new SignControl();
            formSignControl.Show();
        }



 
        [CommandMethod("checksignfiles")]
        public void checksignfiles()
        {
            FormCheckSignFiles form = new FormCheckSignFiles();
            form.Show();
        }

        public static void SetCTB(Transaction trans, ObjectId blockRefId, string strCTB)
        {
            Entity ent = trans.GetObject(blockRefId, OpenMode.ForWrite) as Entity;
            if (ent.ExtensionDictionary != ObjectId.Null)
            {
                DBDictionary ent2 = trans.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary;
                ent2.Remove("MyXrecord");
            }
            else
            {
                ent.CreateExtensionDictionary();
            }
            Xrecord xrec = new Xrecord();
            xrec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, strCTB));
            ObjectId entDictID = ent.ExtensionDictionary;
            DBDictionary entXrecord = trans.GetObject(entDictID, OpenMode.ForWrite) as DBDictionary;
            entXrecord.SetAt("MyXrecord", xrec);
            trans.AddNewlyCreatedDBObject(xrec, true);
            //             Database db = new Database(false, true);
            //             db.ReadDwgFile(path, FileShare.ReadWrite, true, "");
            //             using (Transaction trans = db.TransactionManager.StartTransaction())
            //             {
            //                 BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
            //                 BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
            //                 ObjectId id2 = ObjectId.Null;
            //                 BlockTableRecord btr2 = null;
            //                 foreach (ObjectId id in bt)
            //                 {
            //                     btr2 = trans.GetObject(id, OpenMode.ForWrite) as BlockTableRecord;
            //                     if (Enum.GetNames(typeof(FrameVersionType)).Contains(btr2.Name))
            //                     {
            //                         id2 = id;
            //                         break;
            //                     }
            //                 }
            //                 ObjectIdCollection collection = btr2.GetBlockReferenceIds(true, true);
            //                 foreach (ObjectId id3 in collection)
            //                 {
            //                 }
            // 
            //                 trans.Commit();
            //             }
            //             db.SaveAs(db.Filename, DwgVersion.Current);
            //         }
        }

        static public void PublishFile(String FileName)
        {
            try
            {


                for (; ; )
                {
                    if (PlotFactory.ProcessPlotState == ProcessPlotState.NotPlotting)
                    {
                        break;
                    }
                }

                String MachineName = "DWG To PDF.pc3";
                String PaperName = "";

                Application.DocumentManager.Open(FileName, false);

                FileInfo tfi = new FileInfo(FileName);
                Function.Function_PlotStyle.DownloadPlotStyle(tfi.Name, tfi.Directory.FullName);
                Document doc = Application.DocumentManager.MdiActiveDocument;
                doc.LockDocument();
                Database db = doc.Database;


                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
                    Layout lo = (Layout)tr.GetObject(btr.LayoutId, OpenMode.ForRead);

                    PlotInfo pi = new PlotInfo();
                    pi.Layout = btr.LayoutId;
                    PlotSettings ps = new PlotSettings(lo.ModelType);

                    ps.CopyFrom(lo);
                    PlotSettingsValidator psv = PlotSettingsValidator.Current;

                    psv.SetUseStandardScale(ps, true);
                    psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
                    psv.SetPlotCentered(ps, true);

                    System.Collections.Specialized.StringCollection clo2 = psv.GetPlotDeviceList();
                    System.Collections.Specialized.StringCollection clo3 = psv.GetCanonicalMediaNameList(ps);


                    foreach (String PN in clo3)
                    {
                        Tools.WriteMessageWithReturn(PN);

                        String mediana = psv.GetLocaleMediaName(ps, PN);
                        Tools.WriteMessageWithReturn(mediana);

                    }

                    Tools.WriteMessageWithReturn(MachineName);
                    Tools.WriteMessageWithReturn(PaperName);

                    Double minX = 0;
                    Double minY = 0;
                    Double maxX = 0;
                    Double maxY = 0;

                    foreach (ObjectId blockId in bt)
                    {
                        BlockTableRecord record = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                        if (record.Name.StartsWith("TJAD_TK_A") || record.Name.StartsWith("TJAD_TK_N"))
                        {
                            ObjectIdCollection blockRefIds = record.GetBlockReferenceIds(true, true);
                            Tools.WriteMessageWithReturn(record.Name);
                            Tools.WriteMessageWithReturn(blockRefIds.Count.ToString());
                            foreach (ObjectId blockRefId in blockRefIds)
                            {
                                if (record.Name.Contains("TJAD_TK_A2"))
                                {
                                    PaperName = "UserDefinedMetric (444.00 x 618.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A1"))
                                {
                                    PaperName = "UserDefinedMetric (618.00 x 865.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 1213.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0a_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 1510.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0b_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 1659.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0c_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 1807.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0d_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 1956.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0e_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 2104.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0f_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 2254.00毫米)";
                                }
                                if (record.Name.Contains("TJAD_TK_A0g_"))
                                {
                                    PaperName = "UserDefinedMetric (865.00 x 2402.00毫米)";
                                }
                                Tools.WriteMessageWithReturn(record.Name);
                                Tools.WriteMessageWithReturn(MachineName);
                                Tools.WriteMessageWithReturn(PaperName);
                                BlockReference blockRef = (BlockReference)tr.GetObject(blockRefId, OpenMode.ForRead);
                                string ctbName = null;
                                ctbName = "TJAD_PlotStyle.ctb";

                                try
                                {
                                    System.Collections.Specialized.StringCollection sc = psv.GetPlotStyleSheetList();
                                    foreach (String dd in sc)
                                    {
                                        Tools.WriteMessageWithReturn(dd);
                                    }
                                    psv.SetCurrentStyleSheet(ps, ctbName);
                                }
                                catch (System.Exception ex)
                                {
                                    Tools.WriteMessageWithReturn(ex.ToString());
                                }
                                try
                                {
                                    Extents3d ext = blockRef.GeometricExtents;
                                    Point3d PT1 = ext.MaxPoint;
                                    Point3d PT2 = ext.MinPoint;
                                    minX = System.Math.Min(PT1.X, PT2.X);
                                    minY = System.Math.Min(PT1.Y, PT2.Y);
                                    maxX = System.Math.Max(PT1.X, PT2.X);
                                    maxY = System.Math.Max(PT1.Y, PT2.Y);

                                    Extents2d e2d = new Extents2d(minX, minY, maxX, maxY);
                                    psv.SetPlotWindowArea(ps, e2d);
                                }
                                catch
                                {
                                    ;
                                }
                            }
                        }
                    }

                    psv.SetPlotConfigurationName(ps, MachineName, PaperName);
                    psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Window);
                    psv.SetPlotRotation(ps, PlotRotation.Degrees090);

                    pi.OverrideSettings = ps;

                    PlotInfoValidator piv = new PlotInfoValidator();
                    piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled;
                    piv.Validate(pi);

                    PlotEngine pe = PlotFactory.CreatePublishEngine();
                    using (pe)
                    {
                        PlotProgressDialog ppd = new PlotProgressDialog(false, 1, true);
                        using (ppd)
                        {
                            ppd.set_PlotMsgString(
                              PlotMessageIndex.DialogTitle,
                              "正在打印"//"Custom Plot Progress"
                            );
                            ppd.set_PlotMsgString(
                              PlotMessageIndex.CancelJobButtonMessage,
                              "取消当前打印"//"Cancel Job"
                            );
                            ppd.set_PlotMsgString(
                              PlotMessageIndex.CancelSheetButtonMessage,
                              "取消本页打印"//"Cancel Sheet"
                            );
                            ppd.set_PlotMsgString(
                              PlotMessageIndex.SheetSetProgressCaption,
                              "打印集合进度"//"Sheet Set Progress"
                            );
                            ppd.set_PlotMsgString(
                              PlotMessageIndex.SheetProgressCaption,
                              "打印页进度"//"Sheet Progress"
                            );
                            ppd.LowerPlotProgressRange = 0;
                            ppd.UpperPlotProgressRange = 100;
                            ppd.PlotProgressPos = 0;

                            ppd.OnBeginPlot();
                            ppd.IsVisible = true;
                            pe.BeginPlot(ppd, null);

                            FileInfo fi = new FileInfo(db.Filename);
                            DirectoryInfo di = fi.Directory;
                            DirectoryInfo d2 = new DirectoryInfo(di.Parent.Parent.FullName + @"\PDF\");
                            if (!d2.Exists)
                            {
                                return;
                            }
                            pe.BeginDocument(pi, doc.Name, null, 1, true, di.Parent.Parent.FullName + @"\PDF\" + fi.Name.Substring(0, (fi.Name.Length - 4)));

                            // Which contains a single sheet

                            ppd.OnBeginSheet();

                            ppd.LowerSheetProgressRange = 0;
                            ppd.UpperSheetProgressRange = 100;
                            ppd.SheetProgressPos = 0;

                            PlotPageInfo ppi = new PlotPageInfo();
                            pe.BeginPage(ppi, pi, true, null);
                            pe.BeginGenerateGraphics(null);
                            pe.EndGenerateGraphics(null);

                            // Finish the sheet
                            pe.EndPage(null);
                            ppd.SheetProgressPos = 100;
                            ppd.OnEndSheet();

                            // Finish the document

                            pe.EndDocument(null);

                            // And finish the plot

                            ppd.PlotProgressPos = 100;
                            ppd.OnEndPlot();
                            pe.EndPlot(null);
                        }
                    }

                }

                // tr.Commit();

                FileInfo tff = new FileInfo(db.Filename);
                Tools.WriteMessageWithReturn("finish");


            }
            catch (System.Exception ex)
            {
                Tools.WriteMessageWithReturn(ex.ToString());
                MessageBox.Show("本次打印未成功");
            	
            }

            Document ca = Application.DocumentManager.MdiActiveDocument;
            ca.CloseAndDiscard();
        }

        [CommandMethod("quicksign")]
        public void quicksign()
        {
            QuickSignEx();
        }

        public static void QuickSignEx()
        {
            string tmp = "";
            ProjectChooseForm pcf = new ProjectChooseForm(ref tmp, false);
            pcf.ShowDialog();
            if (path == "")
            {
                return;
            }
            QuickSign(path);
        }

        public static void QuickSign(string ProjectPath)
        {
            string configPath = CommandFrame.getProInfoPath(ProjectPath);
            //MessageBox.Show(configPath);
            if (!File.Exists(configPath))
            {
                MessageBox.Show("配置文件不存在！" + configPath);
                return;
            }
            Dictionary<string, string> signers = new Dictionary<string, string>();
            StringBuilder strb_Temps = new StringBuilder(2048);
            Extern.GetPrivateProfileString("FrameInfo", "Principal", "", strb_Temps, 2048, configPath);
            signers.Add("Principal", strb_Temps.ToString());
            Extern.GetPrivateProfileString("FrameInfo", "Approve", "", strb_Temps, 2048, configPath);
            signers.Add("Approve", strb_Temps.ToString());
            Extern.GetPrivateProfileString("FrameInfo", "Review", "", strb_Temps, 2048, configPath);
            signers.Add("Review", strb_Temps.ToString());

            string folderPath = ProjectPath;
            List<string> filesPath = new List<string>();
            GoThroughDirectory(folderPath, ref filesPath);
            foreach (string filePath in filesPath)
            {
                if (Path.GetExtension(filePath) == ".dwg")
                {
                    List<string> item = new List<string>();
                    Database db = new Database(false, true);
                    db.ReadDwgFile(filePath, System.IO.FileShare.ReadWrite, false, "");

                    item.Clear();
                    item.Add("ApprovedBy");
                    CommandSign.SignDB(db, signers["Approve"], item);
                    item.Clear();
                    item.Add("ReviewedBy");
                    CommandSign.SignDB(db, signers["Review"], item);
                    item.Clear();

                    int start = 0;
                    int iCount2 = 0;
                    for (int iCount = 0; iCount < signers["Principal"].Length; ++iCount)
                    {
                        if (signers["Principal"][iCount] == ';')
                        {
                            item.Clear();
                            item.Add("PrincipalInCharge" + (iCount2 + 1).ToString());
                            CommandSign.SignDB(db, signers["Principal"].Substring(start, iCount - start), item);
                            start = iCount + 1;
                            ++iCount2;
                        }
                    }
                    db.SaveAs(filePath, DwgVersion.Current);
                }
            }
        }
    }
}
